
package com.hlkj.pay.service.common.impl;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.io.File;
import java.time.LocalDateTime;
import java.time.ZoneId;

import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.extension.annotation.Extension;
import com.hlkj.pay.dto.order.SchemeOrderDto;
import com.hlkj.pay.infrastructure.model.common.CommonAppDO;
import com.hlkj.pay.infrastructure.model.order.PayOrderDO;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.binarywang.wx.miniapp.bean.scheme.WxMaGenerateSchemeRequest;
import cn.binarywang.wx.miniapp.config.impl.WxMaDefaultConfigImpl;
import cn.binarywang.wx.miniapp.util.WxMaConfigHolder;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import me.chanjar.weixin.common.error.WxErrorException;

/**
 * @author HlpayTeam
 * @date 2024/12/30 17:42 参考
 *       https://github.com/binarywang/weixin-java-miniapp-demo/blob/master/src/main/java/com/github/binarywang/demo/wx/miniapp/config/WxMaConfiguration.java
 */
@Slf4j
@Service
@RequiredArgsConstructor
@Extension(bizId = "2")
public class WechatMiniAppServiceService implements WechatAppExtPt {

    private final WxMaService wxMaService;

    @Override
    public CommonResult<SchemeOrderDto> urlLink(CommonAppDO commonAppDO, PayOrderDO payOrderDO, String page) {
        if (!wxMaService.switchover(commonAppDO.getAppId())) {
            intiConfig(commonAppDO);
            WxMaConfigHolder.set(commonAppDO.getAppId());
        }
        SchemeOrderDto schemeOrderDto=new SchemeOrderDto();
        schemeOrderDto.setUserName(commonAppDO.getOriginalId());
        try {
            StringBuilder sb = new StringBuilder();
            sb.append("payOrderNo=");
            sb.append(payOrderDO.getPayOrderNo());
            sb.append("&");
            sb.append("amount=");
            sb.append(payOrderDO.getAmount());
            if (!StringUtils.hasText(page)) {
                page = "pages/lump-sum/lump-sum";
            }
            schemeOrderDto.setPath(page+"?"+sb.toString());
            WxMaGenerateSchemeRequest build = WxMaGenerateSchemeRequest.newBuilder().jumpWxa(WxMaGenerateSchemeRequest.JumpWxa.newBuilder().path(page).query(sb.toString()).build())
                    .expireTime(LocalDateTime.now().plusDays(5).atZone(ZoneId.systemDefault()).toEpochSecond()).build();
            String url = this.wxMaService.getWxMaSchemeService().generate(build);
            schemeOrderDto.setSchemeCode(url);
            return CommonResult.success(schemeOrderDto);
        }
        catch (Exception e) {
            log.error(e.getMessage(), e);
            return CommonResult.error(1, e.getMessage());
        }
        finally {
            WxMaConfigHolder.remove();// 清理ThreadLocal
        }
    }

    @Override
    public CommonResult<WxMaJscode2SessionResult> wxAppUserInfo(CommonAppDO commonAppDO, String code) {
        if (!wxMaService.switchover(commonAppDO.getAppId())) {
            intiConfig(commonAppDO);
            WxMaConfigHolder.set(commonAppDO.getAppId());
        }
        try {
            return CommonResult.success(wxMaService.getUserService().getSessionInfo(code));
        }
        catch (WxErrorException e) {
            log.error(e.getMessage(), e);
            return CommonResult.error(1, e.getMessage());
        }
        finally {
            WxMaConfigHolder.remove();// 清理ThreadLocal
        }
    }

    @Override
    public CommonResult<File> getwxacodeunlimit(CommonAppDO commonAppDO, String page,String scene) {
        if (!wxMaService.switchover(commonAppDO.getAppId())) {
            intiConfig(commonAppDO);
            WxMaConfigHolder.set(commonAppDO.getAppId());
        }

        try {
            File file = this.wxMaService.getQrcodeService().createWxaCodeUnlimit(scene,page);
            return CommonResult.success(file);
        }
        catch (Exception e) {
            log.error("getwxacodeunlimit error:{}", e);
            return CommonResult.error(1, e.getMessage());
        }
        finally {
            WxMaConfigHolder.remove();// 清理ThreadLocal
        }
    }

    void intiConfig(CommonAppDO commonAppDO) {
        WxMaDefaultConfigImpl config = new WxMaDefaultConfigImpl();
//                WxMaDefaultConfigImpl config = new WxMaRedisConfigImpl(new JedisPool());
        // 使用上面的配置时，需要同时引入jedis-lock的依赖，否则会报类无法找到的异常
        config.setAppid(commonAppDO.getAppId());
        config.setSecret(commonAppDO.getAppSecret());
        // config.setToken(a.sett());
        // config.setAesKey(a.getAesKey());
        config.setMsgDataFormat("JSON");
        wxMaService.addConfig(commonAppDO.getAppId(), config);
    }
}
